/*
 * Copyright (C) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.tomergoldst.tooltipshm;
import com.ruffian.library.widget.component.RRadioButton;
import ohos.agp.animation.Animator;
import ohos.agp.animation.AnimatorProperty;
import ohos.agp.components.*;
import ohos.agp.utils.TextAlignment;
import java.util.List;

public class ToolTipsManager {
    private static final int ZERO = 0;
    private static final int FIRST = 1;
    private static final int TWO = 2;
    private static final int THREE = 3;
    private static final int FOUR = 4;
    private static final int FIVE = 5;
    private static final int SIX = 6;
    private static final int SEVEN = 7;
    private static final int Eight = 8;
    private static final int DEFAULT_ANIM_DURATION = 400;
    private static final String TIP_TEXT = "Tool Tip";
    private static final String TIP_TEXT_LARGE = "Large Tool Tip";
    private static final String TIP_TEXT_SMALL = "Small tool Tip";
    private TextField mEditText;
    private int mAnimationDuration;
    private ToolTipAnimator mToolTipAnimator;
    private Text idAboveImageview;
    private Text idBelowimageView;
    private Text leftImageView;
    private Text rightImageView;
    private Button mAboveBtn;
    private Button mBelowBtn;
    private Button mLeftToBtn;
    private Button mRightToBtn;
    private RRadioButton checkboxLeft;
    private RRadioButton checkboxCenter;
    private RRadioButton checkboxRight;
    private List<RRadioButton> checkList;
    private List<Button> buttons;
    private List<Image> images;
    private DependentLayout dlInitLayout;
    private Text showTextView;
    private Image imacenterAbove;
    private Image imaAboveLeft;
    private Image imaAboveRight;
    private Image imaLeftCenter;
    private Image imaRightCenter;
    private Image imaBelowLeft;
    private Image imaBelowCenter;
    private Image imaBelowRight;
    private DependentLayout dlAboveleft;
    private DependentLayout dlAboveCenter;
    private DependentLayout dlAboveRight;
    private DependentLayout leftDlView;
    private DependentLayout rightDlView;
    private DependentLayout dlBelowCenter;
    private DependentLayout dlBelowLeft;
    private DependentLayout dlBelowRight;
    private Text tvAboveLeft;
    private Text tvAboveRight;
    private Text belowImageLeft;
    private Text belowImageRight;

    /**
     * empty build ToolTipsManager
     */
    public ToolTipsManager() {
        mAnimationDuration = DEFAULT_ANIM_DURATION;
        mToolTipAnimator = new DefaultToolTipAnimator();
    }

    /**
     * ToolTipsManager
     *
     * @param dependentLayouts 相对布局
     * @param ima 图片
     * @param mText 文本
     * @param texts 文本列表
     * @param btons 按钮
     * @param cList 列表
     */
    public ToolTipsManager(List<DependentLayout> dependentLayouts, List<Image> ima, TextField mText, List<Text> texts,
                           List<Button> btons, List<RRadioButton> cList) {
        this();
        this.mEditText = mText;
        this.checkList = cList;
        this.buttons = btons;
        this.images = ima;
        checkboxLeft = checkList.get(ZERO);
        checkboxCenter = checkList.get(FIRST);
        checkboxRight = checkList.get(TWO);

        mAboveBtn = buttons.get(ZERO);
        mBelowBtn = buttons.get(FIRST);
        mLeftToBtn = buttons.get(TWO);
        mRightToBtn = buttons.get(THREE);

        idAboveImageview = texts.get(ZERO);
        idBelowimageView = texts.get(FIRST);
        leftImageView = texts.get(TWO);
        rightImageView = texts.get(THREE);
        showTextView = texts.get(FOUR);
        tvAboveLeft = texts.get(FIVE);
        tvAboveRight = texts.get(SIX);
        belowImageLeft = texts.get(SEVEN);
        belowImageRight = texts.get(Eight);
        dlAboveleft = dependentLayouts.get(ZERO);
        dlAboveCenter = dependentLayouts.get(FIRST);
        dlAboveRight = dependentLayouts.get(TWO);
        dlInitLayout = dependentLayouts.get(THREE);
        leftDlView = dependentLayouts.get(FOUR);
        rightDlView = dependentLayouts.get(FIVE);
        dlBelowLeft = dependentLayouts.get(SIX);
        dlBelowCenter = dependentLayouts.get(SEVEN);
        dlBelowRight = dependentLayouts.get(Eight);

        imaAboveLeft = images.get(ZERO);
        imacenterAbove = images.get(FIRST);
        imaAboveRight = images.get(TWO);
        imaLeftCenter = images.get(THREE);
        imaRightCenter = images.get(FOUR);
        imaBelowLeft = images.get(FIVE);
        imaBelowCenter = images.get(SIX);
        imaBelowRight = images.get(SEVEN);

        initCheckBoxLeft();
        checkboxCenterClick();
        checkBoxRightClick();
    }

    /**
     * tip show
     *
     * @param tag 标志位
     * @param toolTip tools
     */
    public void show(int tag, ToolTip toolTip) {
        Text tipView = toolTip.getmTextView();
        Image imaAboveCenter = toolTip.getImaAboveLeft();
        imacenterAbove = imaAboveCenter;
        showTextView = tipView;
        if (tag == FIRST) {
            showAbove();
        } else if (tag == TWO) {
            showBelow();
        } else if (tag == THREE) {
            showLeft();
        } else if (tag == FOUR) {
            showRight();
        }
    }

    private void createAbove(Text idImageview, Image imaLeftAbove, int resource) {
        ToolTipBackgroundConstructor.setAboveBackground(idImageview, imaLeftAbove, resource);
    }

    private void createLeft(Text idImageview, Image imaLeftAbove, int resource) {
        ToolTipBackgroundConstructor.setLeftBackground(idImageview, imaLeftAbove, resource);
    }

    private void createRight(Text idImageview, Image imaLeftAbove, int resource) {
        ToolTipBackgroundConstructor.setRightBackground(idImageview, imaLeftAbove, resource);
    }

    private void createBelow(Text idImageview, Image imaLeftAbove, int resource) {
        ToolTipBackgroundConstructor.setBelowBackground(idImageview, imaLeftAbove, resource);
    }

    /**
     * 展示顶部位置
     */
    public void showAbove() {
        dlAboveCenter.setVisibility(Component.VISIBLE);
        imacenterAbove.setVisibility(Component.VISIBLE);
        String textAbove = UiUtils.isEmpty(mEditText.getText()) ? TIP_TEXT : mEditText.getText().toString();
        idAboveImageview.setText(textAbove);
        idAboveImageview.setTextAlignment(TextAlignment.CENTER);
        idAboveImageview.setVisibility(Component.VISIBLE);
        createAbove(idAboveImageview, imacenterAbove, ResourceTable.Media_arrow_down);
        visableabove();
        mToolTipAnimator.popup(idAboveImageview, dlAboveCenter, mAnimationDuration).start();
        idAboveImageview.setClickedListener(component -> findAndDismiss(dlAboveCenter, imacenterAbove));
        dlAboveCenter.setClickedListener(component -> findAndDismiss(dlAboveCenter, imacenterAbove));
    }

    private void visableabove() {
        dlInitLayout.setVisibility(Component.HIDE);
        dlAboveRight.setVisibility(Component.HIDE);
        dlAboveleft.setVisibility(Component.HIDE);
        leftDlView.setVisibility(Component.HIDE);
        rightDlView.setVisibility(Component.HIDE);
        dlBelowLeft.setVisibility(Component.HIDE);
        dlBelowCenter.setVisibility(Component.HIDE);
        dlBelowRight.setVisibility(Component.HIDE);
    }

    /**
     * showAboveLeft
     */
    public void showAboveLeft() {
        dlAboveleft.setVisibility(Component.VISIBLE);
        imaAboveLeft.setVisibility(Component.VISIBLE);
        String textAbove = UiUtils.isEmpty(mEditText.getText()) ? TIP_TEXT : mEditText.getText().toString();
        tvAboveLeft.setText(textAbove);
        tvAboveLeft.setTextAlignment(TextAlignment.CENTER);
        tvAboveLeft.setVisibility(Component.VISIBLE);
        createAbove(tvAboveLeft, imaAboveLeft, ResourceTable.Media_arrow_down);
        visableaboveLeft();
        mToolTipAnimator.popup(tvAboveLeft, dlAboveleft, mAnimationDuration).start();
        tvAboveLeft.setClickedListener(component -> findAndDismiss(dlAboveleft, imaAboveLeft));
        imaAboveLeft.setClickedListener(component -> findAndDismiss(dlAboveleft, imaAboveLeft));
    }

    private void visableaboveLeft() {
        dlInitLayout.setVisibility(Component.HIDE);
        dlAboveRight.setVisibility(Component.HIDE);
        dlAboveCenter.setVisibility(Component.HIDE);
        leftDlView.setVisibility(Component.HIDE);
        rightDlView.setVisibility(Component.HIDE);
        dlBelowLeft.setVisibility(Component.HIDE);
        dlBelowCenter.setVisibility(Component.HIDE);
        dlBelowRight.setVisibility(Component.HIDE);
    }

    /**
     * showAboveRight
     */
    public void showAboveRight() {
        dlAboveRight.setVisibility(Component.VISIBLE);
        imaAboveRight.setVisibility(Component.VISIBLE);
        String textAbove = UiUtils.isEmpty(mEditText.getText()) ? TIP_TEXT : mEditText.getText().toString();
        tvAboveRight.setText(textAbove);
        tvAboveRight.setTextAlignment(TextAlignment.CENTER);
        tvAboveRight.setVisibility(Component.VISIBLE);
        createAbove(tvAboveRight, imaAboveRight, ResourceTable.Media_arrow_down);
        visableaboveRight();
        mToolTipAnimator.popup(tvAboveRight, dlAboveRight, mAnimationDuration).start();
        dlAboveRight.setClickedListener(component -> findAndDismiss(dlAboveRight, imaAboveRight));
    }

    private void visableaboveRight() {
        dlInitLayout.setVisibility(Component.HIDE);
        dlInitLayout.setVisibility(Component.HIDE);
        dlAboveleft.setVisibility(Component.HIDE);
        dlAboveCenter.setVisibility(Component.HIDE);
        leftDlView.setVisibility(Component.HIDE);
        rightDlView.setVisibility(Component.HIDE);
        dlBelowLeft.setVisibility(Component.HIDE);
        dlBelowCenter.setVisibility(Component.HIDE);
        dlBelowRight.setVisibility(Component.HIDE);
    }

    /**
     * 展示底部位置
     */
    public void showBelow() {
        dlBelowCenter.setVisibility(Component.VISIBLE);
        imaBelowCenter.setVisibility(Component.VISIBLE);
        String textBelow = UiUtils.isEmpty(mEditText.getText()) ? TIP_TEXT : mEditText.getText().toString();
        createBelow(idBelowimageView, imaBelowCenter, ResourceTable.Media_media_up);
        idBelowimageView.setVisibility(Component.VISIBLE);
        ToolTipCoordinatesFinder.getPositionBelow(textBelow, idBelowimageView, showTextView);
        visableBelow();
        mToolTipAnimator.popup(idBelowimageView, dlBelowCenter, mAnimationDuration).start();
        idBelowimageView.setClickedListener(component -> findAndDismiss(dlBelowCenter, imaBelowCenter));
        imaBelowCenter.setClickedListener(component -> findAndDismiss(dlBelowCenter, imaBelowCenter));
    }

    private void visableBelow() {
        dlInitLayout.setVisibility(Component.HIDE);
        dlAboveRight.setVisibility(Component.HIDE);
        dlAboveleft.setVisibility(Component.HIDE);
        dlAboveCenter.setVisibility(Component.HIDE);
        leftDlView.setVisibility(Component.HIDE);
        rightDlView.setVisibility(Component.HIDE);
        dlBelowLeft.setVisibility(Component.HIDE);
        dlBelowRight.setVisibility(Component.HIDE);
    }

    /**
     * showBelowLeft
     */
    public void showBelowLeft() {
        dlBelowLeft.setVisibility(Component.VISIBLE);
        imaBelowLeft.setVisibility(Component.VISIBLE);
        String textBelow = UiUtils.isEmpty(mEditText.getText()) ? TIP_TEXT : mEditText.getText().toString();
        belowImageLeft.setText(textBelow);
        belowImageLeft.setTextAlignment(TextAlignment.CENTER);
        belowImageLeft.setVisibility(Component.VISIBLE);
        createBelow(belowImageLeft, imaBelowLeft, ResourceTable.Media_media_up);
        idBelowimageView.setVisibility(Component.VISIBLE);
        visableBelowLeft();
        mToolTipAnimator.popup(belowImageLeft, dlBelowLeft, mAnimationDuration).start();
        dlBelowLeft.setClickedListener(component -> findAndDismiss(dlBelowLeft, imaBelowLeft));
    }

    private void visableBelowLeft() {
        dlInitLayout.setVisibility(Component.HIDE);
        dlAboveRight.setVisibility(Component.HIDE);
        dlAboveleft.setVisibility(Component.HIDE);
        dlAboveCenter.setVisibility(Component.HIDE);
        rightDlView.setVisibility(Component.HIDE);
        leftDlView.setVisibility(Component.HIDE);
        dlBelowCenter.setVisibility(Component.HIDE);
        dlBelowRight.setVisibility(Component.HIDE);
    }

    /**
     * showBelowRight
     */
    public void showBelowRight() {
        dlBelowRight.setVisibility(Component.VISIBLE);
        imaBelowRight.setVisibility(Component.VISIBLE);
        String textBelow = UiUtils.isEmpty(mEditText.getText()) ? TIP_TEXT : mEditText.getText().toString();
        createBelow(belowImageRight, imaBelowRight, ResourceTable.Media_media_up);
        ToolTipCoordinatesFinder.getPositionBelow(textBelow, belowImageRight, showTextView);
        visableBelowRight();
        mToolTipAnimator.popup(belowImageRight, dlBelowRight, mAnimationDuration).start();
        dlBelowRight.setClickedListener(component -> findAndDismiss(dlBelowRight, imaBelowRight));
    }

    private void visableBelowRight() {
        dlInitLayout.setVisibility(Component.HIDE);
        dlAboveRight.setVisibility(Component.HIDE);
        dlAboveleft.setVisibility(Component.HIDE);
        dlAboveCenter.setVisibility(Component.HIDE);
        rightDlView.setVisibility(Component.HIDE);
        leftDlView.setVisibility(Component.HIDE);
        dlBelowLeft.setVisibility(Component.HIDE);
        dlBelowCenter.setVisibility(Component.HIDE);
        dlBelowLeft.setVisibility(Component.HIDE);
    }

    /**
     * 展示左侧位置
     */
    public void showLeft() {
        leftDlView.setVisibility(Component.VISIBLE);
        imaLeftCenter.setVisibility(Component.VISIBLE);
        String textLeft = UiUtils.isEmpty(mEditText.getText()) ? TIP_TEXT_SMALL : mEditText.getText().toString();
        leftImageView.setVisibility(Component.VISIBLE);
        createLeft(leftImageView, imaLeftCenter, ResourceTable.Media_arrow_left);
        leftImageView.setText(textLeft);
        leftImageView.setTextAlignment(TextAlignment.CENTER);
        visableLeft();
        mToolTipAnimator.popup(leftImageView, leftDlView, mAnimationDuration).start();
        leftImageView.setClickedListener(component -> findAndDismiss(leftDlView, imaLeftCenter));
        imaLeftCenter.setClickedListener(component -> dismissAll());
    }

    private void visableLeft() {
        dlInitLayout.setVisibility(Component.HIDE);
        dlAboveRight.setVisibility(Component.HIDE);
        dlAboveleft.setVisibility(Component.HIDE);
        dlAboveCenter.setVisibility(Component.HIDE);
        rightDlView.setVisibility(Component.HIDE);
        dlBelowLeft.setVisibility(Component.HIDE);
        dlBelowCenter.setVisibility(Component.HIDE);
        dlBelowRight.setVisibility(Component.HIDE);
    }

    /**
     * 展示右侧位置
     */
    public void showRight() {
        rightDlView.setVisibility(Component.VISIBLE);
        imaRightCenter.setVisibility(Component.VISIBLE);
        String textRight = UiUtils.isEmpty(mEditText.getText()) ? TIP_TEXT_LARGE : mEditText.getText().toString();
        rightDlView.setVisibility(Component.VISIBLE);
        createRight(rightImageView, imaRightCenter, ResourceTable.Media_arrow_right);
        ToolTipCoordinatesFinder.getPositionRightTo(textRight, showTextView, rightImageView);
        visableRight();
        mToolTipAnimator.popup(rightImageView, rightDlView, mAnimationDuration).start();
        rightImageView.setClickedListener(component -> findAndDismiss(rightDlView, imaRightCenter));
        imaRightCenter.setClickedListener(component -> findAndDismiss(rightDlView, imaRightCenter));
    }

    private void visableRight() {
        dlInitLayout.setVisibility(Component.HIDE);
        dlAboveRight.setVisibility(Component.HIDE);
        dlAboveleft.setVisibility(Component.HIDE);
        dlAboveCenter.setVisibility(Component.HIDE);
        leftDlView.setVisibility(Component.HIDE);
        dlBelowLeft.setVisibility(Component.HIDE);
        dlBelowCenter.setVisibility(Component.HIDE);
        dlBelowRight.setVisibility(Component.HIDE);
    }

    /**
     * dismiss TipView
     */
    public void dismissAll() {
        AnimatorProperty aValue = new AnimatorProperty();
        aValue.alphaFrom(0).alpha(0).setCurveType(new Animator.CurveType().ANTICIPATE_OVERSHOOT).setDuration(500);
        aValue.setTarget(dlInitLayout);
        aValue.start();
        dlInitLayout.setVisibility(Component.HIDE);
        dlAboveRight.setVisibility(Component.HIDE);
        dlAboveleft.setVisibility(Component.HIDE);
        dlAboveCenter.setVisibility(Component.HIDE);
        rightDlView.setVisibility(Component.HIDE);
        leftDlView.setVisibility(Component.HIDE);
        dlBelowLeft.setVisibility(Component.HIDE);
        dlBelowCenter.setVisibility(Component.HIDE);
        dlBelowLeft.setVisibility(Component.HIDE);
    }

    /**
     * dismiss 对话框
     */
    public void dismissDialog() {
        dlInitLayout.setVisibility(Component.HIDE);
        AnimatorProperty abovePopup = new AnimatorProperty();
        abovePopup.alphaFrom(0).alpha(0).setCurveType(new Animator.CurveType().ANTICIPATE).setDuration(1000);
        abovePopup.setTarget(dlInitLayout);
        abovePopup.start();
    }

    /**
     * find Dismiss
     *
     * @param view  DependentLayout
     * @param image Image
     */
    public void findAndDismiss(DependentLayout view, Image image) {
        view.setVisibility(Component.HIDE);
        image.setVisibility(Component.HIDE);
        isAnimateDismiss(view, image);
    }

    private void isAnimateDismiss(final DependentLayout view, Image image) {
        AnimatorProperty abovePopup = new AnimatorProperty();
        abovePopup.alphaFrom(0).alpha(0).setCurveType(new Animator.CurveType().ANTICIPATE).setDuration(1000);
        abovePopup.setTarget(view);
        abovePopup.setTarget(image);
        abovePopup.start();
    }

    private void initCheckBoxLeft() {
        checkboxLeft.setCheckedStateChangedListener(new AbsButton.CheckedStateChangedListener() {
            @Override
            public void onCheckedChanged(AbsButton absButton, boolean isSelect) {
                if (isSelect) {
                    checkboxLeft.setChecked(true);
                    checkboxCenter.setChecked(false);
                    checkboxRight.setChecked(false);
                    mAboveBtn.setClickedListener(new Component.ClickedListener() {
                        @Override
                        public void onClick(Component component) {
                            showAboveLeft();
                            createAbove(idAboveImageview, imaAboveLeft, ResourceTable.Media_arrow_down);
                        }
                    });
                    mBelowBtn.setClickedListener(new Component.ClickedListener() {
                        @Override
                        public void onClick(Component component) {
                            showBelowLeft();
                            createBelow(idBelowimageView, imaBelowLeft, ResourceTable.Media_media_up);
                        }
                    });
                    mLeftToBtn.setClickedListener(new Component.ClickedListener() {
                        @Override
                        public void onClick(Component component) {
                            showLeft();
                            createLeft(leftImageView, imaLeftCenter, ResourceTable.Media_arrow_left);
                        }
                    });
                    mRightToBtn.setClickedListener(new Component.ClickedListener() {
                        @Override
                        public void onClick(Component component) {
                            showRight();
                            createRight(rightImageView, imaLeftCenter, ResourceTable.Media_arrow_right);
                        }
                    });
                }
            }
        });
    }

    private void checkboxCenterClick() {
        checkboxCenter.setCheckedStateChangedListener(new AbsButton.CheckedStateChangedListener() {
            @Override
            public void onCheckedChanged(AbsButton absButton, boolean isSelect) {
                if (isSelect) {
                    checkboxLeft.setChecked(false);
                    checkboxCenter.setChecked(true);
                    checkboxRight.setChecked(false);
                    mAboveBtn.setClickedListener(new Component.ClickedListener() {
                        @Override
                        public void onClick(Component component) {
                            showAbove();
                            createAbove(idAboveImageview, imacenterAbove, ResourceTable.Media_arrow_down);
                        }
                    });
                    mBelowBtn.setClickedListener(new Component.ClickedListener() {
                        @Override
                        public void onClick(Component component) {
                            showBelow();
                            createBelow(idBelowimageView, imaBelowCenter, ResourceTable.Media_media_up);
                        }
                    });

                    mLeftToBtn.setClickedListener(new Component.ClickedListener() {
                        @Override
                        public void onClick(Component component) {
                            showLeft();
                            createLeft(leftImageView, imaLeftCenter, ResourceTable.Media_arrow_left);
                        }
                    });

                    mRightToBtn.setClickedListener(new Component.ClickedListener() {
                        @Override
                        public void onClick(Component component) {
                            showRight();
                            createRight(rightImageView, imaLeftCenter, ResourceTable.Media_arrow_right);
                        }
                    });
                }
            }
        });
    }

    private void checkBoxRightClick() {
        checkboxRight.setCheckedStateChangedListener(new AbsButton.CheckedStateChangedListener() {
            @Override
            public void onCheckedChanged(AbsButton absButton, boolean isSelect) {
                if (isSelect) {
                    checkboxLeft.setChecked(false);
                    checkboxCenter.setChecked(false);
                    checkboxRight.setChecked(true);
                    mAboveBtn.setClickedListener(new Component.ClickedListener() {
                        @Override
                        public void onClick(Component component) {
                            showAboveRight();
                            createAbove(tvAboveRight, imaAboveRight, ResourceTable.Media_arrow_down);
                        }
                    });

                    mBelowBtn.setClickedListener(new Component.ClickedListener() {
                        @Override
                        public void onClick(Component component) {
                            showBelowRight();
                            createBelow(idBelowimageView, imaBelowRight, ResourceTable.Media_media_up);
                        }
                    });

                    mLeftToBtn.setClickedListener(new Component.ClickedListener() {
                        @Override
                        public void onClick(Component component) {
                            showLeft();
                            createLeft(leftImageView, imaLeftCenter, ResourceTable.Media_arrow_left);
                        }
                    });

                    mRightToBtn.setClickedListener(new Component.ClickedListener() {
                        @Override
                        public void onClick(Component component) {
                            showRight();
                            createRight(rightImageView, imaLeftCenter, ResourceTable.Media_arrow_right);
                        }
                    });
                }
            }
        });
    }
}
